昨天通過了第六關之後,今天要來接續第七關
從錯誤看起來,是後端在針對前端提供的 clientDataJSON 進行 base64RawURL 解碼時發生錯誤
那這個錯誤,我們從後端進行修正!
首先看到 controller/assertion.go
中的 FinishAssertionHandler
接著我們修改對 clientDataJSON 進行解碼的方式
首先是 api/assertion.go
中的 AuthenticatorAssertionResponseRequest.Response
原先是使用 protocol.AuthenticatorAssertionResponse
,這邊我們改成自建一個 AuthenticatorAssertionResponse
物件,像是下面這樣
type AuthenticatorAssertionResponse struct {
ClientDataJSON string `json:"clientDataJSON"`
AuthenticatorData string `json:"authenticatorData"`
Signature string `json:"signature"`
UserHandle string `json:"userHandle,omitempty"`
}
再來我們回到 controller/assertion.go
繼續修改 clientDataJSON 的解碼方式
與前面 WebAuthn Registration 的 FinishRegistration
使用相同方式進行解碼
authenticatorClientDataJSON, err := base64.RawURLEncoding.DecodeString(request.Response.ClientDataJSON)
if err != nil {
ctx.JSON(
http.StatusBadRequest,
api.CommonResponse{
Status: "failed",
ErrorMessage: "failed to decode clientDataJSON, error: " + err.Error(),
},
)
return
}
var clientDataJSON map[string]interface{}
if err := json.Unmarshal(authenticatorClientDataJSON, &clientDataJSON); err != nil {
ctx.JSON(
http.StatusBadRequest,
api.CommonResponse{
Status: "failed",
ErrorMessage: "failed to unmarshal clientDataJSON, error: " + err.Error(),
},
)
return
}
接著也將 AuthenticatorAssertionResponseRequest.Response
中的其他欄位 (AuthenticatorData、Signature、UserHandle) 一起進行 base64RawURL 解碼
authenticatorData, err := base64.RawURLEncoding.DecodeString(request.Response.AuthenticatorData)
if err != nil {
ctx.JSON(
http.StatusBadRequest,
api.CommonResponse{
Status: "failed",
ErrorMessage: "failed to decode authenticatorData, error: " + err.Error(),
},
)
return
}
authenticatorSignature, err := base64.RawURLEncoding.DecodeString(request.Response.Signature)
if err != nil {
ctx.JSON(
http.StatusBadRequest,
api.CommonResponse{
Status: "failed",
ErrorMessage: "failed to decode signature, error: " + err.Error(),
},
)
return
}
authenticatorUserHandle, err := base64.RawURLEncoding.DecodeString(request.Response.UserHandle)
if err != nil {
ctx.JSON(
http.StatusBadRequest,
api.CommonResponse{
Status: "failed",
ErrorMessage: "failed to decode userHandle, error: " + err.Error(),
},
)
return
}
因為上面將 Request body 中的 Response 從 protocol.AuthenticatorAssertionResponse
改成我們自己寫的 AuthenticatorAssertionResponse
所以下面 protocol.CredentialAssertionResponse
也需要進行修改
car := protocol.CredentialAssertionResponse{
PublicKeyCredential: protocol.PublicKeyCredential{
Credential: protocol.Credential{
ID: request.Id,
Type: request.Type,
},
RawID: []byte(request.Id),
ClientExtensionResults: request.GetClientExtensionResults,
},
AssertionResponse: protocol.AuthenticatorAssertionResponse{
AuthenticatorResponse: protocol.AuthenticatorResponse{
ClientDataJSON: protocol.URLEncodedBase64(authenticatorClientDataJSON),
},
AuthenticatorData: protocol.URLEncodedBase64(authenticatorData),
Signature: protocol.URLEncodedBase64(authenticatorSignature),
UserHandle: protocol.URLEncodedBase64(authenticatorUserHandle),
},
}
再重新執行一次,就成功通過第七關了~
明天我們再繼續勇闖第八關!